home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / infoserv / gopher / Unix / GopherTools / gophreport2.0.Z / gophreport2.0
Encoding:
Text File  |  1994-08-10  |  18.4 KB  |  554 lines

  1. news.utdallas.edu!tamsun.tamu.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!uwm.edu!ux1.cso.uiuc.edu!news.cso.uiuc.edu!ekatz Mon Mar 22 15:42:22 CST 1993
  2. Article: 1519 of comp.infosystems.gopher
  3. Xref: feenix.metronet.com comp.infosystems.gopher:1519 alt.gopher:113
  4. Newsgroups: comp.infosystems.gopher,alt.gopher
  5. Path: feenix.metronet.com!news.utdallas.edu!tamsun.tamu.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!uwm.edu!ux1.cso.uiuc.edu!news.cso.uiuc.edu!ekatz
  6. From: ekatz@ncsa.uiuc.edu (Eric Katz)
  7. #Subject: GopherReport v.2.0
  8. Date: Mon, 22 Mar 1993 17:14:40 GMT
  9. Message-ID: <1993Mar22.171440.741@ncsa.uiuc.edu>
  10. Distribution: usa
  11. Sender: ekatz@ncsa.uiuc.edu (Eric Katz
  12. Originator: ekatz@landrew.ncsa.uiuc.edu
  13. Organization: Nat'l Ctr for Supercomp App (NCSA) @ University of Illinois
  14. Lines: 536
  15.  
  16. Following is the new release of GopherReport version 2.0.  Thanks to all
  17. who have contributed comments and bug reports.  There are 2 important
  18. items to remember with this new release.  
  19.  
  20. 1. invoking with now arguements now displays a help page.
  21. 2. This version corrects a bug that incorrectly calculated file/directory
  22.    accesses.  I apologize for any inconvenience this may have caused. 
  23.  
  24. See the revision history in the program text for a summary of features
  25. and bug fixes.
  26.  
  27. <<<<<  CUT HERE >>>>
  28.  
  29. #!/usr/local/bin/perl
  30. sub USAGE {
  31. print "USAGE: GopherReport -a|d|t|f|h|e [-s] [-vN] [-l logname] [keys]
  32.     a    All
  33.     d    Daily
  34.     t    Time
  35.     f    Files
  36.     h    Host
  37.     e     Errors
  38.     s    Summary
  39.     l    Name of the log file
  40.     vN    Verbosity
  41.     D    Current Day only\n";
  42. print "    keys    To limit the report to specific days, times, files, and/or
  43.         hosts.  Any combination of keys may be specified.  See
  44.         examples below.
  45.         Try to use the following conventions for the best results:
  46.         Search for a date:   'nn'    ie: 10
  47.         Search for a time:   'nn:'    ie: 10:
  48.         Search for a Day:    'Xxx'    ie: Sun or Sunday
  49.         Search for a file:   'xxx'    ie: software
  50.         or             'xx/'        you may need a leading
  51.         or             '/xx'        or trailing '/'
  52.         Search for a domain: '.xxx'    ie: .edu or ncsa\n\n";
  53.         exit;
  54. }
  55.  
  56. # Written by: Eric Katz
  57. # email:      ekatz@ncsa.uiuc.edu
  58. # If you use this program regularly please send e-mail to the above
  59. # address and I will try to provide you with updated versions as they
  60. # come available.  I am also interested in knowing how often you rotate
  61. # your gopher log and how long you keep old logs.
  62. #########################################################################
  63. #  Permission is granted to anyone to use this software for any purpose on
  64. #  any computer, and to alter it for your personal use.  Please do not
  65. #  distribute any alterations.
  66. #
  67. #  0. This software is provided "as is" and without any express or implied
  68. #     warranties, including, without limitation, the implied warranties of
  69. #     merchantability and fitness for a particular purpose.
  70. #
  71. #  1. The author is not responsible for the consequences of the use of this
  72. #     software, no matter how deleterious, even if they arise from flaws in it.
  73. #
  74. #  2. The origin of this software must not be misrepresented, either by
  75. #     explicit claim or by omission.
  76. #
  77. #
  78. #  3. This software may not be sold.
  79. #
  80. #  4. This notice may not be removed or altered.
  81. #
  82. #########################################################################
  83. # To install - Please remove everthing above the #! line.
  84. # Change the perl path to reflect the location of your perl installation.  
  85. # Then answer the following question.
  86.  
  87. # Whereis your gopher log?
  88. $GopherLOG = "/var/log/gopher_log";
  89.  
  90. ######################################################################
  91. # DO NOT CHANGE ANTHING BELOW THIS LINE FOR DISTRIBUTION. 
  92. # You make may changes for your personal use but DO NO DISTRIBUTE YOUR
  93. # CHANGES.
  94. #
  95. # REVISION HISTORY
  96. # V1.0 Released 2/9/93
  97. # V1.1 Released 2/15/93 
  98. #    Bug Fix: File display now correctly displays file names with spaces
  99. #    Bug Fix: Now handles file names with regexp in them.
  100. #     Bug Fix: Illegal division by zero if no connections for the report
  101. #             period fixed.
  102. #    Bug Fix: Cleaned up output of large file names
  103. #    Feature: Added number of files accessed.
  104. #    Feature: Added varying level of verbosity to the output of file
  105. #         accesses or host accesses.  
  106. #         In the case of file accesses the number represents the depth 
  107. #         of the directory tree that will be printed.  
  108. #         In other words -v1 will only report on root menu accesses, 
  109. #         while -v2 will go one directory deeper and so on.
  110. #         In the case of host accesses, the number represents the
  111. #         top percentile.
  112. #         In other words, -v10 will show the top 10 percent of
  113. #         connections.
  114. #    Feature: Added -s, summary output.  This prints only the total 
  115. #         number of connections and files accessed.
  116. #    Feature: Added search key capability.  Any arguments at the end of
  117. #         the command line are assumed to be search key limiters.
  118. #         It will try to 'do the right thing' but it is safer
  119. #         to limit the type of search by using one of the -d, -t,
  120. #         -f, or -h flags.
  121. #
  122. #
  123. #     EXAMPLES:
  124. #            GopherReport Thu Friday 10 11 14 15 Software
  125. #                Will report on the number of people who
  126. #                accessed the Software files on Thursday
  127. #                and Friday during the 10am, 11am, 2pm, 
  128. #                and 4pm hours.
  129. #            GopherReport -f edu
  130. #                Will report on file accesses that have
  131. #                the edu substring in them.
  132. #            GopherReport -h edu
  133. #                Will report on hosts with edu in the name.
  134. #            GopherReport -fh edu
  135. #                Will report on both hosts and files with 
  136. #                edu in them.
  137. # V2.0 Released 3/22/93
  138. #
  139. #    Bug Fix: Previous version incorrectly tallied bogus entries.
  140. #    Bug Fix: Broke out directory accesses from file retrievals.
  141. #    Feature: Added -l logname capability to examine logfiles other
  142. #         than the default
  143. #    Feature: Added -D to make it easier to examine the logfile for
  144. #         today's information.
  145. #    Feature: Added -e to scan for error messages
  146. ##########################################################################
  147.  
  148. require 'getopts.pl';
  149. require 'ctime.pl';
  150.  
  151. # For now the only date information that is needed is the third field
  152. # regardless of whether it is a BSD system or not but we never know
  153. # what the future holds so I included the following subroutines.
  154. if (-e "/vmunix") {
  155.         $BSD = "true";
  156.         }
  157. else {
  158.         $BSD = "false";
  159. }
  160.  
  161. # Get the current time and format it:
  162. $DATE=&ctime(time),"\n";
  163. if ($BSD eq "true") {
  164.         ($day, $month, $date, $time, $year) = split (" ",$DATE);
  165. }
  166. else {
  167.         ($day, $month, $date, $time, $TZ, $year) = split (" ",$DATE);
  168. }
  169.  
  170. &Getopts('adDtfhesl:v:');
  171.  
  172. # If no options are passed on the command line then display help page.
  173. &USAGE if (!($opt_d) &! ($opt_t) &! ($opt_f) &! ($opt_e) &! ($opt_h) &! ($opt_s)); 
  174.  
  175. # If an alternate logfile has been requested
  176. if (defined $opt_l) {
  177.     $GopherLOG = $opt_l;
  178. }
  179.  
  180. # If you want a printout for today only
  181. #$SearchDate = $date if ($opt_D);
  182. if ($opt_D) {
  183. $SearchDate = "\\b" . $date . "\\b" . "|";
  184. }
  185.  
  186. # If there are no search key limiters.
  187. if (($#ARGV < 0) &! ($opt_D)) {
  188.     $NO_KEY = 1;
  189.     $NO_DAY_KEY = 1;
  190.     $NO_TIME_KEY = 1;
  191.     $NO_OTHERS_KEY = 1;
  192. }
  193.  
  194. # Else create the 'or' pattern matching string
  195. else {
  196.     for ($i=0;$i<=$#ARGV;$i++) {
  197.         if ($ARGV[$i] =~ /Mon|Tue|Wed|Thu|Fri|Sat|Sun/) {
  198.             $SearchDay = $SearchDay . $ARGV[$i] . "|";
  199.         }
  200.         elsif ($ARGV[$i] =~ /\d+:/) {
  201.             chop $ARGV[$i];
  202.             $SearchTime = $SearchTime . $ARGV[$i] . "|";
  203.         }
  204.         elsif ($ARGV[$i] =~ /\d+/) {
  205.         die "This does not make sense with the -D option\n" if ($opt_D);
  206.         $SearchDate = $SearchDate . "\\b" . $ARGV[$i] . "\\b" . "|";
  207.         }
  208.         else {
  209.             $SearchOthers = $SearchOthers . $ARGV[$i] . "|";
  210.         }
  211.     }
  212. }
  213. if (defined $SearchDay) {
  214.     chop ($SearchDay);
  215. }
  216. else {
  217.     $NO_DAY_KEY = 1;
  218. }
  219. if (defined $SearchDate) {
  220.     chop ($SearchDate);
  221. }
  222. else {
  223.     $NO_DATE_KEY = 1;
  224. }
  225. if (defined $SearchTime) {
  226.     chop ($SearchTime);
  227. }
  228. else {
  229.     $NO_TIME_KEY = 1;
  230. }
  231. if (defined $SearchOthers) {
  232.     chop ($SearchOthers);
  233.  
  234. # We need to escape possible wildcard characters in this string, then
  235. # unescape the 'or' character
  236.     $SearchOthers =~ s/\W/\\$&/g;
  237.     $SearchOthers =~ s/\\\|/\|/g;
  238. }
  239. else {
  240.     $NO_OTHERS_KEY = 1;
  241. }
  242.  
  243.  
  244. open (LOG,$GopherLOG) || die "Couldn't open log file\n";
  245.  
  246. # Process the information in the log.
  247. # First, split the line into 2 parts separated by the colon.  This tells
  248. #   you who logged on and what they did.
  249. # Second, split the 'who' variable into the different components.
  250. # Third, split the 'what' variable into it's different components.
  251. # Fourth, If this is the first record in the log then set the start date
  252. #  for the output to the date this entry was made.
  253. # Fifth, set the array information and determine the maximum value for
  254. #  each array.  The maximum value will be used to set the scale for the
  255. #  the graph.
  256. #       If the entry is that of a connection then increment the number
  257. #       of connections, the number of connections for that weekday,
  258. #       the number of connections for that hour of the day, and the
  259. #       number of connections for that host.
  260. #       If the entry is that of an action vs. a connection then increment
  261. #       the number of retrievals for that directory.
  262. #       Sixth, increment the record number.
  263.  
  264. $RECORD_NUMBER = 1;
  265. while (<LOG>) {
  266.         ($who, $what) = split (/ : /,$_,2);
  267.         ($day, $mon, $date, $time, $year, $pid, $host) = split (/\s+/,$who);
  268.         ($action, $file_type, $path) = split (/\s+/,$what,3);
  269.     chop $path;
  270.         ($hour,$minutes,$seconds) = split (/:/,$time);
  271.         if ($RECORD_NUMBER eq 1) {
  272.                 $start_date = "$mon $date, $year @ $time";
  273.         }
  274. # This ridiculously long conditional just tries to do the right thing with
  275. # possible search key limiters
  276. if (($NO_KEY) || ($NO_DAY_KEY || ($day =~ /$SearchDay/)) && ($NO_DATE_KEY || ($date =~ /$SearchDate/)) && ($NO_TIME_KEY || ($hour =~ /$SearchTime/)) && ($NO_OTHERS_KEY || ($path =~ (/$SearchOthers/) || ($host =~ /$SearchOthers/)))) { 
  277.         if ( $file_type =~ /Connection/ ) {
  278.                 $connections ++;
  279.                 $Connect{$day} ++;
  280.               $DayMax = $Connect{$day} if ($Connect{$day} > $DayMax);
  281.                 $Connect{$hour} ++;
  282.               $HourMax = $Connect{$hour} if ($Connect{$hour} > $HourMax);
  283.                 $Machines{$host} ++;
  284.               $HostMax = $Machines{$host} if ($Machines{$host} > $HostMax);
  285.         }
  286.         elsif (($action =~ /retrieved/) &! ($host =~ /^0\./)) {
  287.         if ($file_type =~ /file/) {
  288.                         $FILE_ACCESSES ++;
  289.                         $Directory{$path} ++;
  290.                         $FileMax = $Directory{$path} if ($Directory{$path} > $FileMax);
  291.                 }
  292.                 if ($file_type =~ /directory/) {
  293.                         $DIRECTORY_ACCESSES ++;
  294.                         $Directory{$path} ++;
  295.                         $FileMax = $Directory{$path} if ($Directory{$path} > $FileMax);
  296.                 }
  297.  
  298.         }
  299.     else {
  300.         if ($path =~ /not exist!!/) {
  301.             $EXIST_ERRORS_PRINT = $EXIST_ERRORS_PRINT . "\n$mon $date    $hour:$minutes $action";
  302.             $EXIST_ERRORS_PRINT = $EXIST_ERRORS_PRINT . " $file_type" if ($file_type !~ /does/);
  303.             $EXIST_ERRORS ++;
  304.         }
  305.         else {
  306.             if ($file_type =~ /directory/) {
  307.                 $ACCESS_ERRORS_PRINT = $ACCESS_ERRORS_PRINT . "$mon $date    $hour:$minutes $path\n";
  308.                 $ACCESS_ERRORS ++;
  309.             }
  310.         }
  311.     }
  312.         
  313.  
  314. $RECORD_NUMBER ++;
  315. }
  316. }
  317. close LOG;
  318.  
  319. if ($opt_e) {
  320. print "==================================================================\n";
  321. print "            Gopher Error History\n";
  322. print "              Beginning $start_date\n";
  323. print "              Ending    $end_date\n";
  324. print "==================================================================\n";
  325. print "\n";
  326. print "NON-EXISTING FILES: $EXIST_ERRORS Occurences\nDATE    TIME    FILE\n____________________________________________\n";
  327. if ($EXIST_ERRORS) {
  328. print $EXIST_ERRORS_PRINT;
  329. }
  330. print "\n\nNON-ACCESSIBLE DIRECTORIES: $ACCESS_ERRORS Occurences\nDATE    TIME    FILE\n____________________________________________\n";
  331. if ($ACCESS_ERRORS) {
  332. print $ACCESS_ERRORS_PRINT;
  333. }
  334. }
  335.  
  336. # Set the end date variable to that of the last entry in the log.
  337. $end_date = "$mon $date, $year @ $time";
  338.  
  339.  
  340. if ($opt_a) {
  341.     $opt_d = 1;
  342.     $opt_h = 1;
  343.     $opt_t = 1;
  344.     $opt_f = 1;
  345. }
  346. # This number represents either the number of subdirectory levels to report
  347. # or the top x percentage of host connections depending on the context.
  348. if (defined $opt_v){
  349.     $verbosity_limit = $opt_v;
  350. }
  351. else {
  352.     $verbosity_limit = 100;
  353. }
  354.  
  355. # Set an array to convert 3 letter weekday abbreviations to full names.
  356. @weekdays = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
  357.  
  358. #  Print the header
  359. print "\n\n";
  360. print "==================================================================\n";
  361. print "            Gopher Usage Report\n";
  362. print "              Beginning $start_date\n";
  363. print "              Ending    $end_date\n";
  364. print "==================================================================\n";
  365. print "\n";
  366. print "                     Successful    Failed\n";
  367. print "                    ------------   ---------\n";
  368. print  "Total Number of Connections:             $connections\n";
  369. print  "Total Number of Files Retrieved:         $FILE_ACCESSES        $EXIST_ERRORS\n";
  370. print  "Total Number of Directories Accessed:    $DIRECTORY_ACCESSES        $ACCESS_ERRORS\n";
  371. print "\n";
  372. exit if ($opt_s);
  373.  
  374. if ($opt_d) {
  375. $SubTotal=0;
  376. # Print the connections/weekday data
  377. print "\n";
  378. print "Connections Per Week Day\n";
  379.  
  380.         printf ("%-8s%-30s\n%s\n"," Day","Connections","---------------------------------------------------------------------");
  381.  
  382. # Print the output for each record.
  383.  
  384. foreach $heading (@weekdays) {
  385. # Convert the heading for each day (long form) into the short form for
  386. # accessing the array information.
  387. $index = substr($heading,0,3);
  388. # Calculate the number of stars to print.
  389.     if ($DayMax > 0 ){
  390.         $graph = '*' x ($Connect{$index} / $DayMax * 50);
  391.     }
  392.     else {
  393.     $graph = "";
  394.     }
  395. # Print them.
  396.     if (($index =~ /$SearchDay/) || $NO_DAY_KEY) {
  397.             printf ("%-13s%3s %s\n",$heading,$Connect{$index},$graph);
  398.     $SubTotal = $SubTotal + $Connect{$index};
  399.     }
  400. }
  401. print "\n";
  402. print "Total for this Section: $SubTotal\n\n" if !($NO_KEY);
  403. }
  404.  
  405. if ($opt_t) {
  406. $SubTotal=0;
  407. # Iterate through the 'Hours' array to print the hourly information.  The
  408. # first 10 numbers are quoted to preserve the leading 0.
  409. @Hours = ('00','01','02','03','04','05','06','07','08','09',10 .. 23);
  410. print "\n";
  411. print "Connections Per Hour\n";
  412.         printf ("%-8s%-30s\n%s\n"," Hour","Connections","---------------------------------------------------------------------");
  413. foreach $heading (@Hours) {
  414.         if ($HourMax > 0 ){
  415.         $graph = '*' x ($Connect{$heading} / $HourMax * 50);
  416.         }
  417.         else {
  418.         $graph = "";
  419.         }
  420.     if (($heading =~ /$SearchTime/) || $NO_TIME_KEY) {
  421.     $SubTotal = $SubTotal + $Connect{$heading};
  422. # Change the heading to read 'Midnight' if appropriate
  423.         if ($heading == '00') {
  424.                 printf ("%-12s%4s %s\n","Midnight",$Connect{$heading},$graph);
  425.         }
  426. # Change the heading to read 'Noon' if appropriate
  427.        elsif ($heading == '12') {
  428.                 printf ("%-12s%4s %s\n","Noon",$Connect{$heading},$graph);
  429.         }
  430. # Else just print the hour by number.
  431.         else {
  432.                 printf ("%-12s%4s %s\n",$heading,$Connect{$heading},$graph);
  433.         }
  434. }
  435. }
  436. print "\n";
  437. print "Total for this Section: $SubTotal\n\n" if !($NO_TIME_KEY);
  438. }
  439. if ($opt_f) {
  440. $SubTotal=0;
  441. print "\n";
  442. print "Access Report for Directories and Files\n\n";
  443. printf ("%s\n%s\n","Directory or File Accessed","-------------------------------------------------------------------------");
  444. # Set an array of full pathnames
  445. @DIRS = keys(%Directory);
  446.  
  447. # Sort that array.
  448. @sortedDIRS = sort @DIRS;
  449.  
  450. foreach $heading (@sortedDIRS) {
  451. # Calculate the number of stars for each entry (I add 1 just so that
  452. # each line gets at least 1 star for visual reasons.  This actually sets
  453. # the scale off a bit but it is just meant to be a quick reference any
  454. # way.  If you want more accurate graphing remove the '+ 1' in the following
  455. # line.
  456. # Calculate the number of stars to print.
  457.  
  458. # StringLength is used in order to split the filename into multiple
  459. # lines if it exceeds 30 characters.
  460. $StringLength = 0;
  461.         if ($FileMax > 0 ){
  462.         $graph = '*' x (($Directory {$heading} / $FileMax * 30) + 1);
  463.         }
  464.         else {
  465.         $graph = "";
  466.         }
  467. # Create an array consisting of the names in the full path without
  468. # the '/'
  469.         @heading_format = split (/\//,$heading);
  470.  
  471.     
  472. $PRINT_ME = 1 if ($heading =~ /$SearchOthers/);
  473.  
  474. # Iterate through this list of file names that defines the path.  For each
  475. # name in this path that is the same as the path of the previously printed 
  476. # file name prepend a leading '.' to the name.  
  477. # This is all to prevent the duplication of full pathnames in the output 
  478. # to make it more readable.
  479.  
  480.         for ($i=1;$i < $#heading_format;$i++) {
  481.                 if ($heading_format[$i] eq $previous_heading[$i]) {
  482.                         $heading_format[$i] = ".";
  483.                 }
  484.         else {
  485.             $heading_format[$i] = $heading_format[$i] . "/";
  486.         }
  487.  
  488.         $StringLength = $StringLength + length($heading_format[$i]);
  489.         if ($StringLength > 30){
  490.             $heading_format[$i] = $heading_format[$i] . "\n   ";
  491.             $StringLength = 3;
  492.         }
  493.         }
  494.  
  495. # Pad the output to create nice columns.  printf doesn't handle the 
  496. # multiple line filenames very well.
  497. $Spaces = " " x (37 - ($StringLength + length ($heading_format[$i])));
  498. $heading_format[$i] = "$heading_format[$i]$Spaces";
  499.  
  500. # If this is the root menu then label it as such.
  501.         if ($heading eq "\/") {
  502.                 @heading_format = "Main_Menu                            ";
  503.         }
  504.  
  505. # Set the printed array element delimiter to null
  506. $" = "";
  507.  
  508. # Print it.
  509. if ($i <= $verbosity_limit) {
  510.     if ($PRINT_ME || $NO_OTHERS_KEY) {
  511.     $SubTotal = $SubTotal + $Directory{$heading};
  512.         printf ("%s%5s %s\n","@heading_format",$Directory{$heading},$graph);
  513.         #printf ("%-35s%5s %s\n","@heading_format",$Directory{$heading},$graph);
  514.     }
  515. }
  516.  
  517. # Set this to be the previously printed filename.
  518.         @previous_heading = split (/\//,$heading);
  519.     $PRINT_ME = 0;
  520. }
  521. print "\n";
  522. print "Total for this Section: $SubTotal\n\n" if !($NO_KEY);
  523. }
  524.  
  525. if ($opt_h) {
  526. $SubTotal=0;
  527.  
  528. # Print the name of each host and the number of time they connected.
  529. print "Connections per Host\n";
  530. sub by_connections {
  531.     $Machines{$b} <=> $Machines{$a};
  532. }
  533. @HOSTS = keys(%Machines);
  534. @sortedHOSTS = sort by_connections @HOSTS;
  535.         printf ("%-30s%s\n%s\n","Host ","Number of Connections","---------------------------------------------------------------------");
  536. foreach $heading (@sortedHOSTS) {
  537.     if (($heading =~ /$SearchOthers/) || $NO_OTHERS_KEY) {
  538.         if ($SubTotal < ($connections * ($verbosity_limit)/100)){
  539.         $SubTotal = $SubTotal + $Machines{$heading};
  540.                printf ("%-50s%s\n",$heading,$Machines{$heading});
  541.         }
  542.     }
  543. }
  544. print "\n";
  545. print "Total for this Section: $SubTotal\n\n" if !($NO_KEY);
  546. }
  547. -- 
  548.  
  549. ===============================================
  550. Eric Katz (ekatz@ncsa.uiuc.edu)
  551. Computer Utilization Analyst
  552.  
  553.  
  554.